use std::borrow::{Borrow, BorrowMut};
use std::ops::{Deref, DerefMut};
use List::{Cons, Nil};
use std::rc::Rc;
use std::cell::RefCell;

pub fn run(){
    let a  = Some(1);
    let aa = {
       if let Some(_) = a{
           true
       }else{
           false
       }
    };
    println!("aa={}",aa);

    rc();
}
fn rc(){
    let x = &Rc::new(String::from("123"));  // 1.第一个引用
    let x2 = Rc::clone(x);       //2. 第二个引用
    let closures = move ||{
         let clone_x = Rc::clone(x);  //3. 第三个引用
         // println!("x = {}",x);
         println!("1. strong_count count ={}", Rc::strong_count(&clone_x));
     };
     closures(); // 闭包结束后，引用释放 还剩两个
     println!("2. strong_count count ={}", Rc::strong_count(&x));
     println!("x ={}", *x);
     {
        let x2 = Rc::clone(x);       //4. 第四个引用;前面还有两个引用 这里 强引用数量是3
        println!("3. strong_count count ={}", Rc::strong_count(&x2));
     }
    //  出了作用域，强引用还有 2

     let wr = Rc::downgrade(x);
     println!("4. x={}, weakcount={}, strong_count={}", wr.upgrade().expect("弱引用不存在"), wr.weak_count(), Rc::strong_count(x)); // upgrade()获取了一个强引用 ，强引用：3
     println!("5. closures count ={}", Rc::strong_count(&x2)); // 上一步 获取强引用后方法执行完，引用释放，最终强引用数量：2
}
fn refcell(){
    struct Person{
        name: RefCell<String>,
    }
    
    let p = Person{name: RefCell::new("John".to_string())};
    println!("name={}", p.name.borrow());
    *p.name.borrow_mut() = "123".to_string();
    println!("name={}", &p.name.borrow());
}
fn drop_(){
    let mut nn = NumCat{num:1};
    nn.num = 12;
    std::mem::drop(nn);
    // println!("nn={}", nn.num);
    println!("after drop().");
}
#[derive(Debug)]
enum List {
    Cons(i32, RefCell<Rc<List>>),
    Nil,
}
impl List {
    fn tail(&self) -> Option<&RefCell<Rc<List>>> {
        
        match self {
            Cons(_, item) => Some(item),
            Nil => None,
        }
    }
}

struct NumCat{
    num: i32,
}
impl Drop for NumCat{
    fn drop(&mut self) {
        println!("drop NumCat-{}",self.num);
    }
}
impl Deref for NumCat{
    type Target = i32;

    fn deref(&self) -> &Self::Target{
        &self.num
    }
}
fn deref_t(){
    let mut nc = NumCat{num:1};
    println!("nc.num={}", nc.num);
    println!("*nc={}", *nc); //和 nc.num 同样的效果
    
    // *nc = 13;
    // println!("*nc={}", *nc);
}